package fi.profecons.csswindows;

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.Iterator;
import java.util.List;

import javax.imageio.IIOImage;
import javax.imageio.ImageIO;
import javax.imageio.ImageWriteParam;
import javax.imageio.ImageWriter;
import javax.imageio.stream.ImageOutputStream;
import javax.servlet.ServletContext;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileItemFactory;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;

import fi.profecons.csswindows.toolkit.FileUpload;
import fi.profecons.csswindows.toolkit.Image;

class FileHandler {

	public void uploadFile(HttpServletRequest request, ServletContext context,
			State state) {
		FileUpload fileUpload = state.getFileUpload();
		if (fileUpload != null && ServletFileUpload.isMultipartContent(request)) {
			fileUpload.initialize();
			FileItemFactory factory = new DiskFileItemFactory();
			ServletFileUpload upload = new ServletFileUpload(factory);
			upload.setProgressListener(new FileUploadProgressListener(
					fileUpload));
			try {
				List items = upload.parseRequest(request);
				Iterator i = items.iterator();
				while (i.hasNext()) {
					FileItem item = (FileItem) i.next();
					if (!item.isFormField()) {
						if (fileUpload.getRelativePath() != null) {
							fileUpload.setPath(context.getRealPath(fileUpload
									.getRelativePath()));
						}
						fileUpload.processFileItem(item);
					}
				}
			} catch (FileUploadException fue) {
			}
		}
	}

	private void sendBinaryFile(HttpServletRequest request,
			HttpServletResponse response, String disposition) {
		try {
			String path = request.getParameter("path");
			String filename = request.getParameter("filename");
			FileInputStream fis = new FileInputStream(path + filename);
			response.setContentType("application/octet-stream");
			response.addHeader("Content-Disposition", disposition
					+ "; filename=" + filename);
			int b;
			ServletOutputStream sos = response.getOutputStream();
			while ((b = fis.read()) != -1) {
				sos.write(b);
			}
			fis.close();

		} catch (IOException ie) {
		}

	}

	public void sendBinaryFile(HttpServletRequest request,
			HttpServletResponse response) {
		sendBinaryFile(request, response, "inline");
	}

	public void sendBinaryFileDownload(HttpServletRequest request,
			HttpServletResponse response) {
		sendBinaryFile(request, response, "attachment");
	}

	public void sendTextFile(HttpServletRequest request,
			HttpServletResponse response) {
		try {
			String path = request.getParameter("path");
			String filename = request.getParameter("filename");
			PrintWriter out = response.getWriter();
			if (filename.endsWith(".js")) {
				response.setContentType("application/x-javascript");
			}
			response.addHeader("Content-Disposition", "inline; filename="
					+ filename);
			if (path == null) {
				path = "/";
			}
			out.println(readFile(path + filename));
		} catch (IOException ie) {
		}
	}

	private String readFile(String s) {
		String line;
		StringBuffer sb = new StringBuffer();
		InputStream is = getClass().getResourceAsStream(s);
		BufferedReader br = new BufferedReader(new InputStreamReader(is));
		try {
			while ((line = br.readLine()) != null) {
				sb.append(line);
				sb.append("\r\n");
			}
		} catch (IOException e) {
		}
		return sb.toString();
	}

	public void sendImage(HttpServletRequest request,
			HttpServletResponse response) {
		HttpSession session = request.getSession(true);
		State state = (State) session.getAttribute("state");
		String id = request.getParameter("image_id");

		if (state != null) {
			Image image = (Image) state.get(id);
			response.setContentType("image/jpeg");
			try {
				Iterator writers = ImageIO.getImageWritersByFormatName("jpeg");
				ImageWriter writer = (ImageWriter) writers.next();
				ServletOutputStream sos = response.getOutputStream();
				ImageOutputStream ios = ImageIO.createImageOutputStream(sos);
				writer.setOutput(ios);
				ImageWriteParam param = writer.getDefaultWriteParam();
				param.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
				param.setCompressionQuality(image.getQuality());
				writer.write(null, new IIOImage(image.getBuffer(), null, null),
						param);
				response.setContentLength((int)ios.length());
				ios.close();
			} catch (IOException ie) {
			}

		}

	}

	public void sendImageFile(HttpServletRequest request,
			HttpServletResponse response) {
		HttpSession session = request.getSession(true);
		State state = (State) session.getAttribute("state");
		String id = request.getParameter("image_id");

		if (state != null) {
			Image image = (Image) state.get(id);
			response.setContentType("image/jpeg");
			try {
				FileInputStream fis = new FileInputStream(image.getFile());
				response.addHeader("Content-Disposition", "inline"
						+ "; filename=" + image.getFile().getName());
				response.setContentLength((int)image.getFile().length());
				int b;
				ServletOutputStream sos = response.getOutputStream();
				while ((b = fis.read()) != -1) {
					sos.write(b);
				}
				fis.close();

			} catch (IOException ie) {
			}
		}

	}

	public void fileUploadStatus(HttpServletRequest request,
			HttpServletResponse response) {
		try {
			PrintWriter out = response.getWriter();
			HttpSession session = request.getSession();
			State state = (State) session.getAttribute("state");
			FileUpload fileUpload = state.getFileUpload();
			out.write("getElement('" + fileUpload.getStatusBar().getId()
					+ "').setValue('" + fileUpload.getPercent() + "');");
			if (fileUpload.getPercent() == 100) {
				out.write("getElement('" + fileUpload.getStatusBar().getId()
						+ "').stop();");
				out.write("getElement('" + fileUpload.getId()
						+ "').uploadComplete();");
			}
			out.flush();
			out.close();
		} catch (IOException e) {
		}
	}

	public void fileUploadComplete(State state) {
		FileUpload fileUpload = state.getFileUpload();
		if (fileUpload.isUploadOk()) {
			fileUpload.uploadReady();
		} else {
			fileUpload.uploadFailure();
		}
	}

}
